<html>
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<head>
<title>Section 13.2.&nbsp; PHP and HTTP Authentication</title>
<link rel="STYLESHEET" type="text/css" href="images/style.css">
<link rel="STYLESHEET" type="text/css" href="images/docsafari.css">
</head>
<body>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=learnphpmysql-CHP-13-SECT-1.html><img src="images/prev.gif" width="60" height="17" border="0" align="absmiddle" alt="Previous Page"></a>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=learnphpmysql-CHP-13-SECT-3.html><img src="images/next.gif" width="60" height="17" border="0" align="absmiddle" alt="Next Page"></a>
</div></td></tr></table>
<br><table width="100%" border="0" cellspacing="0" cellpadding="0"><tr><TD valign="top"><a name="learnphpmysql-CHP-13-SECT-2"></a>
<h3 id="631450-961" class="docSection1Title">13.2. PHP and HTTP Authentication</h3>
<p class="docText">PHP can use authentication from the Apache web server. PHP sends a header request to the browser requesting an authentication dialog on the client's browser. You'll recognize this prompt as a standard browser login prompt. Because the authentication head must come before any other HTML output, this works only with the module-based PHP installation, not the CGI version.</p>
<p class="docText"><a class="docLink" href="#learnphpmysql-CHP-13-EX-4">Example 13-4</a> shows how to use HTTP authentication.<a name="IDX-CHP-13-0612"></a> 
</p>
<a name="learnphpmysql-CHP-13-EX-4"></a><h5 id="title-IDAIVMAJ" class="docExampleTitle">Example 13-4. Using HTTP authentication with a PHP script</h5><p><table cellspacing="0" width="90%" border="1" cellpadding="5"><tr><td>

<pre>
&lt;?php
if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])) {
header('WWW-Authenticate: Basic realm="Member Area"');
header("HTTP/1.0 401 Unauthorized");
echo "Please login with a valid username and password.";
exit;
} else {
echo "You entered a username of: ".$_SERVER['PHP_AUTH_USER']." ";
echo "and a password of: ".$_SERVER['PHP_AUTH_PW'].".";
}
?&gt;
</pre><br>

</td></tr></table></P>
<p class="docText">The code from <a class="docLink" href="#learnphpmysql-CHP-13-EX-4">Example 13-4</a> displays a prompt like the one in <a class="docLink" href="#learnphpmysql-CHP-13-FIG-2">Figure 13-2</a>.</p>
<a name="learnphpmysql-CHP-13-FIG-2"></a><p><center>
<H5 class="docFigureTitle">Figure 13-2. The prompt for authentication to the Member Area realm</H5>
<img border="0" alt="" id="195131084204" width="405" height="241" SRC="images/learnphpmysql_1302.jpg">
</center></p><BR>
<p class="docText">If the user clicks Cancel, he'll see <a class="docLink" href="#learnphpmysql-CHP-13-FIG-3">Figure 13-3</a>.</p>
<a name="learnphpmysql-CHP-13-FIG-3"></a><p><center>
<h5 class="docFigureTitle">Figure 13-3. Clicking Cancel causes a message that the user must log in</H5>
<img border="0" alt="" id="195131084204" width="549" height="171" SRC="images/learnphpmysql_1303.jpg">
</center></p><BR>
<p class="docText">That's a fairly simple example. We checked to see if the username and password were set, then displayed them to the user. The <tt>realm</tt> field provides a way for grouping related pages together for access restrictions. Any PHP page that presents the authentication headers within the same realm as the login page is accessible after a successful login. This spares the user from having to re-authenticate for each PHP page.</p>
<p class="docText"><a class="docLink" href="#learnphpmysql-CHP-13-EX-5">Example 13-5</a> validates the username and password retrieved from an authentication prompt. If they don't match, access to all pages in that realm is denied.</p>
<a name="learnphpmysql-CHP-13-EX-5"></a><H5 id="title-IDAKXMAJ" class="docExampleTitle">Example 13-5. Checking the values returned from the authentication prompt</H5><p><table cellspacing="0" width="90%" border="1" cellpadding="5"><TR><td>

<pre>
&lt;?php
$username = 'jon_doe';
$password = 'MyNameIsJonDoe';
if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])) {
header('WWW-Authenticate: Basic realm="Member Area"');
header("HTTP/1.0 401 Unauthorized");
echo "You must enter in a username and password combination!";
exit;
}
elseif (strcmp($_SERVER['PHP_AUTH_USER'], $username) !== 0 ||
strcmp($_SERVER['PHP_AUTH_PW'], $password) !== 0) {
header('WWW-Authenticate: Basic realm="Member Area"');
header("HTTP/1.0 401 Unauthorized");
echo "Your username and password combination was incorrect!";
exit;
}
echo("You have successfully logged in!");
?&gt;
</pre><br>

</TD></TR></table></p>
<p class="docText"><a class="docLink" href="#learnphpmysql-CHP-13-EX-5">Example 13-5</a> checks that the authentication was set. If it wasn't, request a username and password. The <tt>elseif</tt> clause checks to see whether the strings are equal to each other.</p>
<p class="docText">This is different than simply comparing two strings with the equality (<tt>==)</tt> operator. When comparing input, the <tt>==</tt> operator can cause unexpected results. Therefore, use the <tt>strcmp</tt> function. The <tt>strcmp</tt> function returns 0 only when the two strings are identical. If either the username or password comparison returns a value other than 0, you deny access; otherwise, access is granted. If they don't match, request another authentication prompt from the user by sending authentication headers again. They then must come before any other output.</p>
<a name="learnphpmysql-CHP-13-SECT-2.1"></a>
<h4 id="title-IDAKYMAJ" class="docSection2Title">13.2.1. Storing a Username and Password in a Database</H4>
<a name="IDX-CHP-13-0613"></a> 
<a name="IDX-CHP-13-0614"></a> 
<a name="IDX-CHP-13-0615"></a> 
<a name="IDX-CHP-13-0616"></a> 

<p class="docText">Let's revisit some of the knowledge you picked up back in <a class="docLink" href="learnphpmysql-CHP-5.html#learnphpmysql-CHP-5">Chapter 5</a>. We're going to create a new table for users. Instead of comparing a username and password to values that are set in your PHP script, you'll check them against a database table called <tt>USERS</tt>. As explained in <a class="docLink" href="learnphpmysql-CHP-5.html#learnphpmysql-CHP-5">Chapter 5</a>, you'll want to log into the command prompt and create a table using the syntax in <a class="docLink" href="#learnphpmysql-CHP-13-EX-6">Example 13-6</a>.</p>
<a name="learnphpmysql-CHP-13-EX-6"></a><H5 id="title-IDAYZMAJ" class="docExampleTitle">Example 13-6. Creating the users table to store login information</h5><p><table cellspacing="0" width="90%" border="1" cellpadding="5"><TR><TD>

<pre>
CREATE TABLE `users` (
`user_id` INT NOT NULL AUTO_INCREMENT,
`first_name` VARCHAR(100),
`last_name` VARCHAR(100),
`username` VARCHAR(45),
`password` CHAR(32),
PRIMARY KEY (`user_id`));
</pre><br>

</TD></tr></table></p>
<p class="docText">This code returns:</p>
<pre>
Query OK, 0 rows affected (0.23 sec)
</pre><br>

<p class="docText">To add a user, you create an entry in the database for a user with an encrypted password, as shown in <a class="docLink" href="#learnphpmysql-CHP-13-EX-7">Example 13-7</a>.</p>
<a name="learnphpmysql-CHP-13-EX-7"></a><h5 id="title-IDAN0MAJ" class="docExampleTitle">Example 13-7. Creating the entry in the database for a user with an encrypted password</h5><p><table cellspacing="0" width="90%" border="1" cellpadding="5"><tr><td>

<pre>
INSERT INTO users (`first_name`, `last_name`, `username`, `password`)
VALUES
('Michele','Davis', 'mdavis', MD5('secret'));
</pre><br>

</td></TR></table></p>
<p class="docText">This yields:</p>
<pre>
Query OK, 1 row affected (0.01 sec)
</pre><BR>

<p class="docText">To check that your row was created and see what the <tt>MD5</tt> encoding function returned, you query the <tt>users</tt> table:</P>
<pre>
SELECT * FROM users;
</pre><br>

<p class="docText">Presto:</P>
<pre>
+---------+------------+-----------+----------+----------------------------------+
| user_id | first_name | last_name | username | password |
+---------+------------+-----------+----------+----------------------------------+
|       1 | Michele    | Davis     | mdavis   | 5ebe2294ecd0e0f08eab7690d2a6ee69 |
+---------+------------+-----------+----------+----------------------------------+
1 row in set (0.00 sec)
</pre><br>

<p class="docText">Now that you've created the table, let's set up the login script to test a username and password. You encoded the password using <tt>MD5</tt> to provide an extra layer of security. The password that created the encoded string cannot be determined from the stored string. This means that even if a malicious user finds out another user's encoded password, she can't use it to log in. However, this method is for testing only, and more secure options will be discussed later in the book.</p>
<p class="docText"><a class="docLink" href="learnphpmysql-CHP-13-SECT-3.html#learnphpmysql-CHP-13-EX-10">Example 13-10</a> reuses much of the same code from the example in the previous section, so don't worry about having to rewrite too much! The major difference is that instead of using the <tt>strcmp</tt> command to check the username and password, you place them into a query and use the database to check for a match.</p>
<p class="docText">Don't forget that you still need your database login information in a file called <span class="docEmphasis">db_login.php</span>, shown in <a class="docLink" href="#learnphpmysql-CHP-13-EX-8">Example 13-8</a>.</P>
<a name="learnphpmysql-CHP-13-EX-8"></a><h5 id="title-IDAA2MAJ" class="docExampleTitle">Example 13-8. The database login details</H5><p><table cellspacing="0" width="90%" border="1" cellpadding="5"><tr><TD>

<pre>
&lt;?php
$db_host='localhost';
$db_database='test';
$db_username='test';
$db_password='yourpass';
?&gt;
</pre><BR>

</td></TR></table></p>
<p class="docText">The values from <a class="docLink" href="#learnphpmysql-CHP-13-EX-8">Example 13-8</a> are used in <a class="docLink" href="#learnphpmysql-CHP-13-EX-9">Example 13-9</a>.</p>
<a name="learnphpmysql-CHP-13-EX-9"></a><H5 id="title-IDAW2MAJ" class="docExampleTitle">Example 13-9. Verifying a username and password against the database</H5><p><table cellspacing="0" width="90%" border="1" cellpadding="5"><tr><td>

<pre>
&lt;?php
require_once('db_login.php');
require_once('DB.php');
if (!isset($_SERVER['PHP_AUTH_USER']) ||
!isset($_SERVER['PHP_AUTH_PW'])) {
header('WWW-Authenticate: Basic realm="Member Area"');
header("HTTP/1.0 401 Unauthorized");
echo "You must enter in a username and password combination!";
exit;
}
$web_username = $_SERVER['PHP_AUTH_USER'];
$web_password = $_SERVER['PHP_AUTH_PW'];
$connection = DB::connect("mysql://$db_username:$db_password@$db_host/$db_database");
if (DB::isError($connection)){
die ("Could not connect to the database: &lt;br /&gt;". DB::errorMessage($connection));
}
$query = "SELECT `user_id`, `username` FROM `users` WHERE
`username`='".$web_username."' AND `password`=MD5('".$web_password."') LIMIT 1";
$result = $connection-&gt;query($query);
if (DB::isError($result)){
die("Could not query the database: &lt;br /&gt;".$query." ".DB::errorMessage($result));
}
if (!$row = $result-&gt;fetchRow(DB_FETCHMODE_ASSOC)) {
header('WWW-Authenticate: Basic realm="Member Area"');
header("HTTP/1.0 401 Unauthorized");
echo "Your username and password combination was incorrect!";
exit;
}
echo("You have successfully logged in as ".$row['username']."!");
?&gt;
</pre><br>

</TD></tr></table></P>
<p class="docText">You may have to change <tt>display_errors = Off</tt> in the <span class="docEmphasis">php.ini</span> file if you get the following error.</p>
<pre>
Warning:  headers already sent message causing the message box not to display.
</pre><br>

<p class="docText">This may be a little too much to consume at the moment, but save the script and run it, which displays the screen in <a class="docLink" href="#learnphpmysql-CHP-13-FIG-4">Figure 13-4</a>. Then try logging in with the username of <tt>mdavis</tt> and a password of <tt>secret</tt>.</P>
<a name="learnphpmysql-CHP-13-FIG-4"></a><P><center>
<h5 class="docFigureTitle">Figure 13-4. Prompting for username and password before checking the database</H5>
<img border="0" alt="" id="195131084204" width="457" height="214" SRC="images/learnphpmysql_1304.jpg">
</center></p><br>
<p class="docText">You should see that the script handles the login, shown in <a class="docLink" href="#learnphpmysql-CHP-13-FIG-5">Figure 13-5</a>, with the database because there is a successful match of data.</p>
<a name="learnphpmysql-CHP-13-FIG-5"></a><p><center>
<h5 class="docFigureTitle">Figure 13-5. A successful match with the database's credentials</h5>
<img border="0" alt="" id="195131084204" width="527" height="163" SRC="images/learnphpmysql_1305.jpg">
</center></p><br>
<p class="docText">If you entered something invalid, you'll see an unauthorized page such as <a class="docLink" href="#learnphpmysql-CHP-13-FIG-6">Figure 13-6</a> telling you that the username and password are incorrect.</p>
<a name="learnphpmysql-CHP-13-FIG-6"></a><p><center>
<h5 class="docFigureTitle">Figure 13-6. An invalid username and password causes this message to display</h5>
<img border="0" alt="" id="195131084204" width="531" height="173" SRC="images/learnphpmysql_1306.jpg">
</center></P><br>


</TD></TR></table>
<br>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=learnphpmysql-CHP-13-SECT-1.html><img src="images/prev.gif" width="60" height="17" border="0" align="absmiddle" alt="Previous Page"></a>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=learnphpmysql-CHP-13-SECT-3.html><img src="images/next.gif" width="60" height="17" border="0" align="absmiddle" alt="Next Page"></a>
</div></td></tr></table>
<script type="text/javascript"><!--
google_ad_client = "pub-0203281046321155";
google_alternate_ad_url = "http://www.bookhtml.com/adbrite.htm";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "text_image";
google_ad_channel ="4867465545";
google_color_border = "FFFFFF";
google_color_link = "0000FF";
google_color_bg = "FFFFFF";
google_color_text = "000000";
google_color_url = "0000FF";
//--></script>
<script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</html>
